#ifndef DSPNASM_ELFFILE_H
#define DSPNASM_ELFFILE_H

#include <string>
#include <vector>
#include <memory>
#include <unordered_map>
#include "lit/elf/elf.h"
#include "lit/elf/linker.h"
#include "lit/elf/relocationItem.h"

struct ElfFile {
    std::string fileName;   // elf文件名
    Elf32_Ehdr ehdr;        // elf文件头
    std::vector<std::shared_ptr<Elf32_Phdr>> phdrTable; // elf程序头部表
    std::vector<std::string> shdrNames; // 节名
    std::unordered_map<std::string, std::shared_ptr<Elf32_Shdr>> shdrTable; // 节表
    std::vector<std::string> symbolNames; // 符号名
    std::unordered_map<std::string, std::shared_ptr<Elf32_Sym>> symbolTable; // 符号表
    std::vector<std::shared_ptr<RelocationItem>> relTable;  // 重定位表
    std::string shstrtab;   // 节名字符串表
    std::string strtab; // 字符串表

    /**
     * 读取elf文件数据
     * @param fileName elf文件名
     */
    void readElf(const std::string &fileName);

    void getData(char *buffer, Elf32_Off offset, Elf32_Word size) const;

    void assemObj(Linker *linker);

    void addSym(const std::string &symName, std::shared_ptr<Elf32_Sym> sym);

    void addPhdr(Elf32_Word type, Elf32_Off off, Elf32_Addr vaddr, Elf32_Word filesz,
                 Elf32_Word memsz, Elf32_Word flags, Elf32_Word align);

    void addShdr(std::string sh_name, Elf32_Word sh_type, Elf32_Word sh_flags, Elf32_Addr sh_addr, Elf32_Off sh_offset,
                 Elf32_Word sh_size, Elf32_Word sh_link, Elf32_Word sh_info, Elf32_Word sh_addralign,
                 Elf32_Word sh_entsize);

    void writeElf(Linker *linker, const std::string &fileName);
};

#endif //DSPNASM_ELFFILE_H
